package com.campus.counseling.controller;

import com.campus.counseling.model.common.Result;
import com.campus.counseling.model.common.exception.ServiceException;
import com.campus.counseling.entity.ChatSession;
import com.campus.counseling.model.dto.ChatMessageDTO;
import com.campus.counseling.model.dto.ChatSessionDTO;
import com.campus.counseling.model.dto.MessageAck;
import com.campus.counseling.model.mapper.CounselorMapper;
import com.campus.counseling.service.ChatService;
import com.campus.counseling.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.messaging.simp.user.SimpUserRegistry;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.List;

@RestController
@RequestMapping("/api/chat")
@RequiredArgsConstructor
public class ChatController {

    private final SimpMessagingTemplate messagingTemplate;
    private final ChatService chatService;
    private final CounselorMapper counselorMapper;
    private final SimpUserRegistry userRegistry;
    private static final Logger log = LoggerFactory.getLogger(ChatController.class);

    /**
     * WebSocket消息处理
     */
    @MessageMapping("/chat.send")
    public void sendMessage(@Payload ChatMessageDTO message, Principal principal) {
        log.info("====== 开始处理新消息 ======");
        log.info("1. 收到消息详情: {}", message);
        log.info("2. 发送者信息: principal={}, name={}", principal, principal.getName());
        log.info("3. 消息路由信息: senderId={}, receiverId={}, appointmentId={}", 
            message.getSenderId(), message.getReceiverId(), message.getAppointmentId());
        
        try {
            // 保存消息到数据库
            chatService.saveMessage(message);
            log.info("4. 消息已保存到数据库");
            
            // 检查接收者是否在线
            boolean isReceiverOnline = userRegistry.getUser(message.getReceiverId().toString()) != null;
            log.info("5. 接收者在线状态: online={}, receiverId={}", isReceiverOnline, message.getReceiverId());
            
            // 发送消息给接收者
            String receiverId = message.getReceiverId().toString();
            log.info("6. 准备发送消息给接收者: receiverId={}", receiverId);
            
            messagingTemplate.convertAndSendToUser(
                receiverId,
                "/queue/messages",
                message
            );
            log.info("7. 消息已发送给接收者");
            
            // 只发送确认消息给发送者
            messagingTemplate.convertAndSendToUser(
                principal.getName(),
                "/queue/ack",
                new MessageAck(
                    message.getId(),
                    "DELIVERED",
                    message.getAppointmentId(),
                    message.getSenderId()
                )
            );
            log.info("8. 确认消息已发送给发送者");
            
            log.info("====== 消息处理完成 ======");
            
        } catch (Exception e) {
            log.error("消息处理失败:", e);
            messagingTemplate.convertAndSendToUser(
                principal.getName(),
                "/queue/ack",
                new MessageAck(
                    message.getId(),
                    "error",
                    message.getAppointmentId(),
                    message.getSenderId()
                )
            );
            throw e;
        }
    }

    /**
     * 获取或创建会话
     */
    @GetMapping("/session/{appointmentId}")
    public Result<ChatSessionDTO> getOrCreateSession(@PathVariable Long appointmentId) {
        if (appointmentId == null || appointmentId <= 0) {
            throw new ServiceException("无效的预约ID");
        }
        ChatSession session = chatService.getOrCreateSession(appointmentId);
        ChatSessionDTO dto = convertToDTO(session);
        return Result.success(dto);
    }

    private ChatSessionDTO convertToDTO(ChatSession session) {
        ChatSessionDTO dto = new ChatSessionDTO();
        BeanUtils.copyProperties(session, dto);
        return dto;
    }

    /**
     * 获取活跃会话列表
     */
    @GetMapping("/sessions")
    public Result<List<ChatSessionDTO>> getActiveSessions() {
        Long counselorId = SecurityUtils.getUserId();
        log.info("获取咨询师 {} 的活跃会话列表", counselorId);
        Long studentId = SecurityUtils.getUserId();
        log.info("获取学生 {} 的活跃会话列表", studentId);
        List<ChatSessionDTO> sessions = chatService.getActiveSessions(studentId);
        return Result.success(sessions);
    }

    /**
     * 获取聊天历史记录
     */
    @GetMapping("/history/{appointmentId}")
    public Result<List<ChatMessageDTO>> getChatHistory(@PathVariable Long appointmentId) {
        log.info("获取会话 {} 的历史记录", appointmentId);
        List<ChatMessageDTO> history = chatService.getChatHistory(appointmentId);
        return Result.success(history);
    }

    /**
     * 标记消息为已读
     */
    @PostMapping("/read/{appointmentId}")
    public Result<Void> markAsRead(@PathVariable Long appointmentId) {
        Long currentUserId = SecurityUtils.getUserId();
        chatService.markAsRead(currentUserId, appointmentId);
        return Result.success();
    }

    /**
     * 结束会话
     */
    @PostMapping("/session/{appointmentId}/end")
    public Result<Void> endSession(@PathVariable Long appointmentId) {
        log.info("结束会话请求: appointmentId={}", appointmentId);
        chatService.endSession(appointmentId);
        return Result.success();
    }

    @PostMapping("/message/{messageId}/recall")
    public Result<Void> recallMessage(@PathVariable Long messageId) {
        chatService.recallMessage(messageId, SecurityUtils.getUserId());
        return Result.success();
    }
} 